<!DOCTYPE html>
<html lang="en">

<!-- Head tag -->
<head><meta name="generator" content="Hexo 3.8.0">

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!--Description-->

    

    
        <meta name="description" content="参考：https://www.jianshu.com/p/5ce11c20a9df     http://www.imooc.com/article/68207     音频：https://my.oschina.net/u/2326611/blog/854488
一、协议概述RTMP(Real T">
    

    <!--Author-->
    
        <meta name="author" content="Cyrus">
    

    <!--Open Graph Title-->
    
        <meta property="og:title" content="RTMP协议解析">
    

    <!--Open Graph Description-->
    
        <meta property="og:description" content="参考：https://www.jianshu.com/p/5ce11c20a9df     http://www.imooc.com/article/68207     音频：https://my.oschina.net/u/2326611/blog/854488
一、协议概述RTMP(Real T">
    

    <!--Open Graph Site Name-->
        <meta property="og:site_name" content="Cyrus的技术空间">

    <!--Type page-->
    
        <meta property="og:type" content="article">
    

    <!--Page Cover-->
    
    
        <meta property="og:image" content="http://cyrus_huang.gitee.io/bloghttp://www.codeblocq.com/assets/projects/hexo-theme-clean-blog/img/home-bg.jpg">
    

        <meta name="twitter:card" content="summary_large_image">

    

    
        <meta name="twitter:image" content="http://cyrus_huang.gitee.io/bloghttp://www.codeblocq.com/assets/projects/hexo-theme-clean-blog/img/home-bg.jpg">
    

    <!-- Title -->
    
    <title>RTMP协议解析 - Cyrus的技术空间</title>

    <!-- Bootstrap Core CSS -->
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">

    <!-- Custom CSS -->
    <link rel="stylesheet" href="/blog/css/style.css">

    <!-- Custom Fonts -->
    <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" type="text/css">
    <link href="//fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic" rel="stylesheet" type="text/css">
    <link href="//fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" rel="stylesheet" type="text/css">

    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
    <script src="//oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->

    <!-- Gallery -->
    <link href="//cdnjs.cloudflare.com/ajax/libs/featherlight/1.3.5/featherlight.min.css" type="text/css" rel="stylesheet">

    <!-- Google Analytics -->
    


    <!-- favicon -->
    

</head>


<body>

    <!-- Menu -->
    <!-- Navigation -->
<nav class="navbar navbar-default navbar-custom navbar-fixed-top">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header page-scroll">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="/blog/">Cyrus的技术空间</a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav navbar-right">
                
                    <li>
                        <a href="/blog/">
                            
                                Home
                            
                        </a>
                    </li>
                
                    <li>
                        <a href="/blog/archives">
                            
                                Archives
                            
                        </a>
                    </li>
                
                    <li>
                        <a href="/blog/tags">
                            
                                Tags
                            
                        </a>
                    </li>
                
                    <li>
                        <a href="/blog/categories">
                            
                                Categories
                            
                        </a>
                    </li>
                
                    <li>
                        <a href="https://github.com/klugjo/hexo-theme-clean-blog">
                            
                                <i class="fa fa-github fa-stack-2x"></i>
                            
                        </a>
                    </li>
                
            </ul>
        </div>
        <!-- /.navbar-collapse -->
    </div>
    <!-- /.container -->
</nav>

    <!-- Main Content -->
    <!-- Page Header -->
<!-- Set your background image for this header in your post front-matter: cover -->

<header class="intro-header" style="background-image: url('http://www.codeblocq.com/assets/projects/hexo-theme-clean-blog/img/home-bg.jpg')">
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                <div class="post-heading">
                    <h1>RTMP协议解析</h1>
                    
                    <span class="meta">
                        <!-- Date and Author -->
                        
                            Posted by Cyrus on
                        
                        
                            2019-08-06
                        
                    </span>
                </div>
            </div>
        </div>
    </div>
</header>

<!-- Post Content -->
<article>
    <div class="container">
        <div class="row">

            <!-- Tags and categories -->
           
                <div class="col-lg-4 col-lg-offset-2 col-md-5 col-md-offset-1 post-tags">
                    
                        


<a href="/blog/tags/RTMP/">#RTMP</a>


                    
                </div>
                <div class="col-lg-4 col-md-5 post-categories">
                    
                        

<a href="/blog/categories/音视频/">音视频</a>

                    
                </div>
            

            <!-- Gallery -->
            

            <!-- Post Main Content -->
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                <p>参考：<a href="https://www.jianshu.com/p/5ce11c20a9df" target="_blank" rel="noopener">https://www.jianshu.com/p/5ce11c20a9df</a><br>     <a href="http://www.imooc.com/article/68207" target="_blank" rel="noopener">http://www.imooc.com/article/68207</a><br>     音频：<a href="https://my.oschina.net/u/2326611/blog/854488" target="_blank" rel="noopener">https://my.oschina.net/u/2326611/blog/854488</a></p>
<h3 id="一、协议概述"><a href="#一、协议概述" class="headerlink" title="一、协议概述"></a>一、协议概述</h3><p>RTMP(Real Time Messaging Protocol)实时消息传送协议是AdobeSystems公司为Flash播放器和服务器之间音频、视频和数据传输 开发的开放协议。<br>它有多种变种：</p>
<ul>
<li>RTMP工作在TCP之上，默认使用端口1935；</li>
<li>RTMPE在RTMP的基础上增加了加密功能；</li>
<li>RTMPT封装在HTTP请求之上，可穿透防火墙；</li>
<li>RTMPS类似RTMPT，增加了TLS/SSL的安全功能。</li>
</ul>
<h3 id="二、协议详细介绍"><a href="#二、协议详细介绍" class="headerlink" title="二、协议详细介绍"></a>二、协议详细介绍</h3><p>RTMP协议(Real Time Messaging Protocol)是被Flash用于对象，视频，音频的传输。这个协议建立在TCP协议或者轮询HTTP协议之上。<br>RTMP协议就像一个用来装数据包的容器,这些数据既可以是AMF格式的数据，也可以是FLV中的视/音频数据。<br>一个单一的连接可以通过不同的通道传输多路网络流，这些通道中的包都是按照固定大小的包传输的。</p>
<h3 id="三、握手请求及应答"><a href="#三、握手请求及应答" class="headerlink" title="三、握手请求及应答"></a>三、握手请求及应答</h3><p>要建立一个有效的RTMP Connection链接，首先要“握手”:客户端要向服务器发送C0,C1,C2（按序）三个chunk，服务器向客户端发送S0,S1,S2（按序）三个chunk，然后才能进行有效的信息传输。RTMP协议本身并没有规定这6个Message的具体传输顺序，但RTMP协议的实现者需要保证这几点：</p>
<ul>
<li>客户端要等收到S1之后才能发送C2</li>
<li>客户端要等收到S2之后才能发送其他信息（控制信息和真实音视频等数据）</li>
<li>服务端要等到收到C0之后发送S1</li>
<li>服务端必须等到收到C1之后才能发送S2</li>
<li>服务端必须等到收到C2之后才能发送其他信息（控制信息和真实音视频等数据）</li>
</ul>
<p>如果每次发送一个握手chunk的话握手顺序会是这样：<br><img src="http://cyrus_huang.gitee.io/blog/2019/08/06/RTMP协议解析/握手.png" alt=""></p>
<p>理论上来讲只要满足以上条件，如何安排6个Message的顺序都是可以的，但实际实现中为了在保证握手的身份验证功能的基础上尽量减少通信的次数，一般的发送顺序是这样的，这一点可以通过wireshark抓ffmpeg推流包进行验证：<br>｜client｜Server｜<br>｜－－－C0+C1—-&gt;|<br>｜&lt;－－S0+S1+S2–|<br>｜－－－C2-－－－&gt;｜ </p>
<p>下面让我们看一下Wireshark的抓包数据:<br><img src="http://cyrus_huang.gitee.io/blog/2019/08/06/RTMP协议解析/握手_1.png" alt=""><br><img src="http://cyrus_huang.gitee.io/blog/2019/08/06/RTMP协议解析/握手_2.png" alt=""><br><img src="http://cyrus_huang.gitee.io/blog/2019/08/06/RTMP协议解析/握手_3.png" alt=""><br>从上面的过程可以看出： </p>
<ul>
<li>C0 == S0 == 03 为协议版本</li>
<li>C1/C2/S1/S2 分别为1536字节的data,且S2 == C1, C2 == S1</li>
</ul>
<h3 id="四、信息传输"><a href="#四、信息传输" class="headerlink" title="四、信息传输"></a>四、信息传输</h3><p>rtmp的传输遵循RTMP Header + RTMP Body 的结构，如下图所示：<br><img src="http://cyrus_huang.gitee.io/blog/2019/08/06/RTMP协议解析/rtmp_chunk.png" alt=""><br>首先，让我们看一下RTMP Header的结构：</p>
<h4 id="1、RTMP-Header"><a href="#1、RTMP-Header" class="headerlink" title="1、RTMP Header"></a>1、RTMP Header</h4><ul>
<li>RTMP Header 的第一个字节称为basic header, 包含 2bit的fmt + 6bit 的csid(chunk stream ID（流通道Id）。fmt的值决定着RTMP Header 的长度，fmt为0/2/3时，对应的header长度为12/8/4/1(包含basic header本身的一个字节）。</li>
<li>Chunk Msg Header,根据fmt的值，长度为11/7/3/1， 以最长的11字节为例，分别为 时间戳（3字节，以ms为单位，可保存约4.66h的视频），message length(3字节，用来表示后面RTMP Body数据的长度，即图中Chunk data), 消息类型type id（1字节，来以区分该消息块的类型，如音频（0x08)、视频(0x09)、script(0x12)及其它操作,stream id消息流id,4字节。</li>
<li>Extend Timestamp:0/4 bytes,该字段发送的时候必须是正常的时间戳设置成0xffffff时，当正常时间戳不为0xffffff时，该字段不发送。当时间戳比0xffffff小该字段不发送，当时间戳比0xffffff大时该字段必须发送，且正常时间戳设置成0xffffff。</li>
</ul>
<h4 id="2、RTMP-Body"><a href="#2、RTMP-Body" class="headerlink" title="2、RTMP Body"></a>2、RTMP Body</h4><p>对于RTMP Body，我们主要对照抓包数据，解析几种消息类型如音频（0x08)、视频(0x09)、script(0x12)的解析方法。</p>
<h5 id="首先，看一下script的解析"><a href="#首先，看一下script的解析" class="headerlink" title="首先，看一下script的解析"></a>首先，看一下script的解析</h5><p><img src="http://cyrus_huang.gitee.io/blog/2019/08/06/RTMP协议解析/script.png" alt=""><br>RTMP Header:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">04 00 00 00 00 01 7c 12 01 00 00 00</span><br><span class="line"></span><br><span class="line">首字节：0x04即 fmt=0, 确定了header总长度为12  csid=4</span><br><span class="line">时间戳：00 00 00，还未正式传输音视频数据</span><br><span class="line">body长度：00 01 7c（380，注意这里采用大端结构，部分平台需要转换字节序）</span><br><span class="line">type id: 0x12(script类型，包含MetaData)</span><br><span class="line">stream id：01 00 00 00（1）</span><br></pre></td></tr></table></figure></p>
<p>RTMP Body,在解析body之后，我们需要先看一下<br><img src="http://cyrus_huang.gitee.io/blog/2019/08/06/RTMP协议解析/amf_type.png" alt=""><br>类型比较多，这边主要讲一下00(number,即double)，02(字符串)，03（object[string + value]组， 以00 00 09结束）</p>
<p>下面看一组抓包数据：<br><img src="http://cyrus_huang.gitee.io/blog/2019/08/06/RTMP协议解析/script.png" alt=""><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line">02 00 0d 40 73 65 74 44 61 74 61 46 72 61 6d 65</span><br><span class="line">02 00 0a 6f 6e 4d 65 74 61 44 61 74 61 03 00 06   </span><br><span class="line">61 75 74 68 6f 72 02 00 00 00 09 63 6f 70 79 72</span><br><span class="line">69 67 68 74 02 00 00 00 0b 64 65 73 63 72 69 70   </span><br><span class="line">74 69 6f 6e 02 00 00 00 08 6b 65 79 77 6f 72 64   </span><br><span class="line">73 02 00 00 00 06 72 61 74 69 6e 67 02 00 00 00 </span><br><span class="line">05 74 69 74 6c 65 02 00 00 00 0a 70 72 65 73 65 </span><br><span class="line">74 6e 61 6d 65 02 00 06 43 75 73 74 6f 6d 00 0c</span><br><span class="line">63 72 65 61 74 69 6f 6e 64 61 74 65 02 00 19 53  </span><br><span class="line">75 6e 20 4a 75 6e 20 30 34 20 30 30 3a 33 31 3a   </span><br><span class="line">30 38 20 32 30 31 37 0a 00 0b 76 69 64 65 6f 64  </span><br><span class="line">65 76 69 63 65 02 00 15 55 53 42 32 2e 30 20 56   </span><br><span class="line">47 41 20 55 56 43 20 57 65 62 43 61 6d 00 09 66   </span><br><span class="line">72 61 6d 65 72 61 74 65 00 40 2e 00 00 00 00 00  </span><br><span class="line">00 00 05 77 69 64 74 68 00 40 74 00 00 00 00 00   </span><br><span class="line">00 00 06 68 65 69 67 68 74 00 40 6e 00 00 00 00   </span><br><span class="line">00 00 00 0c 76 69 64 65 6f 63 6f 64 65 63 69 64   </span><br><span class="line">02 00 04 61 76 63 31 00 0d 76 69 64 65 6f 64 61  </span><br><span class="line">74 61 72 61 74 65 00 40 7f 40 00 00 00 00 00 00   </span><br><span class="line">08 61 76 63 6c 65 76 65 6c 00 40 3f 00 00 00 00  </span><br><span class="line">00 00 00 0a 61 76 63 70 72 6f 66 69 6c 65 00 40  </span><br><span class="line">50 80 00 00 00 00 00 00 17 76 69 64 65 6f 6b 65  </span><br><span class="line">79 66 72 61 6d 65 5f 66 72 65 71 75 65 6e 63 79 </span><br><span class="line">00 3f f0 00 00 00 00 00 00 00 00 09 </span><br><span class="line">==============     解析       ==============</span><br><span class="line">02(字符串) 00 0d(长度13) 40 73 65 74 44 61 74 61 46 72 61 6d 65(@setDataFrame)</span><br><span class="line">02(字符串) 00 0a(长度10) 6f 6e 4d 65 74 61 44 61 74 61(onMetaData)</span><br><span class="line">03(object)</span><br><span class="line">每一组：00 06(长度为6的字符串) 61 75 74 68 6f 72(author) 02 00 00(长度为0的字符串，即&quot;&quot;)</span><br><span class="line">第二组:00 09(长度为9的字符串) 63 6f 70 79 72 69 67 68 74(copyright) 02 00 00(长度为0的字符串，即&quot;&quot;)</span><br><span class="line">。。。。。。</span><br><span class="line">第十组：00 09(长度为9的字符串) 66 72 61 6d 65 72 61 74 65(framerate) 00(number, 后面跟8字节的值) 00 40 2e 00 00 00 00 00 00(大端值，转小端double后为15)                   </span><br><span class="line">。。。。。。                    </span><br><span class="line">00 00 09(object 结束标志）</span><br></pre></td></tr></table></figure></p>
<h5 id="再看一下video的解析"><a href="#再看一下video的解析" class="headerlink" title="再看一下video的解析"></a>再看一下video的解析</h5><p>视频数据主要分为3种，sps和pps参数集数据，I帧数据，B/P帧数据</p>
<ul>
<li>先看看sps和pps数据解析<br><img src="http://cyrus_huang.gitee.io/blog/2019/08/06/RTMP协议解析/sps.png" alt=""></li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line">04 00 00 00 00 00 43 09 01 00 00 00 17 00 00 00</span><br><span class="line">00 01 42 00 1f 03 01 00 2f 67 42 80 1f 96 52 02</span><br><span class="line">83 f6 02 a1 00 00 03 00 01 00 00 03 00 3c e0 60</span><br><span class="line">01 e8 40 00 11 8c 3f c6 38 c0 c0 03 d0 80 00 23</span><br><span class="line">18 7f 8c 70 ed 0a 15 24 01 00 04 68 cb 8d 48</span><br><span class="line">==============     解析       ==============</span><br><span class="line">header:</span><br><span class="line">	04(fmt+csid) 00 00 00(timestamp) 00 00 43(body size 67) 09(video) 01 00 00 00(stream id 1)</span><br><span class="line"></span><br><span class="line">body:</span><br><span class="line">	0x17 = 0b0001 0111</span><br><span class="line">    	前4bit,1 = key frame (for AVC, a seekable frame)关键帧sps+pps/I帧</span><br><span class="line">               2 = inter frame (for AVC, a non-seekable frame) B/P帧</span><br><span class="line">               3 = disposable inter frame (H.263 only)</span><br><span class="line">               4 = generated key frame (reserved for server use only)</span><br><span class="line">               5 = video info/command frame</span><br><span class="line">		后4bit,2 = Sorenson H.263</span><br><span class="line">               3 = Screen video</span><br><span class="line">               4 = On2 VP6</span><br><span class="line">               5 = On2 VP6 with alpha channel</span><br><span class="line">               6 = Screen video version 2</span><br><span class="line">               7 = AVC</span><br><span class="line">所以，0x17为AVC关键帧</span><br><span class="line"></span><br><span class="line">	00：AVCPacketType，如果是avc，即首字节后四位为7，即</span><br><span class="line">    	0 = AVC sequence header，序列参数集sps+pps</span><br><span class="line">        1 = AVC NALU,视频裸数据</span><br><span class="line">		2 = AVC end of sequence (lower level NALU sequence ender is not required or supported)</span><br><span class="line">        </span><br><span class="line">	00 00 00：CompositionTime</span><br><span class="line">    	IF AVCPacketType == 1</span><br><span class="line">        	Composition time offset</span><br><span class="line">		ELSE</span><br><span class="line">    		0</span><br><span class="line">            </span><br><span class="line">    01：configuration Version</span><br><span class="line"> 	42：AVCProfileIndication</span><br><span class="line"> 	00 1f 03：</span><br><span class="line">    01：后5bit表示sps长度，即0x01&amp;0x1F = 1,1个sps</span><br><span class="line">    00 2f: sps长度</span><br><span class="line">    SPS数据：67 42 80 1f 96 52 02 83 f6 02 a1 00 00 03 00 01 00 00 03 00 3c e0 60 01 e8 40 00 11 8c 3f c6 38 c0 c0 03 d0 80 00 23 18 7f 8c 70 ed 0a 15 24</span><br><span class="line">    01： pps个数</span><br><span class="line">    00 04： pps长度</span><br><span class="line">    PPS数据：68 cb 8d 48</span><br></pre></td></tr></table></figure>
<p>I帧：<br><img src="http://cyrus_huang.gitee.io/blog/2019/08/06/RTMP协议解析/I帧.png" alt=""></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">04 00 00 00 00 03 b8 09 01 00 00 00 17 01 00 02</span><br><span class="line">4b 00 00 03 af 65 88 80 40 07 6c 29 89 00 01 0b</span><br><span class="line">fc f6 ff f8 ec 73 78 59 62 f9 f1 47 53 e1 61 e7</span><br><span class="line">bc 42 a0 f8 60 65 3d e2 b7 88 1e f2 f7 8a de 2b</span><br><span class="line">78 a3 78 81 ef 77 88 7b dd e2 1c 7b 9f 10 f6 88</span><br><span class="line">cb 8d 12 af 51 64 d7 fa 65 24 51 95 eb a5 a2 5c</span><br><span class="line">ae e5 e5 dd e2 b2 e2 1e 5c a6 4b d7 .......</span><br><span class="line">==============     解析       ==============</span><br><span class="line">header:解析方式与sps/pps的header一致</span><br><span class="line">	04 00 00 00 00 03 b8(长度952) 09（video） 01 00 00 00</span><br><span class="line"></span><br><span class="line">body:</span><br><span class="line">	17: avc 关键帧</span><br><span class="line">    01: 视频裸数据，17 01即I帧</span><br><span class="line">    00 02 4b: CompositionTime</span><br><span class="line">    00 00 03 af: nalu size 裸数据长度943，body长度（952）- 9bytes(17 01 00 02 4b 00 00 03 af),刚好为943</span><br><span class="line">    Raw Data: 65 88 80 40 07 6c 29 89 00 01 0b fc f6 ff f8 ec 73 78 59 62 f9 f1 47 53 e1 61 e7 bc 42 a0 f8 60 65 3d e2 b7 88 1e f2 f7 8a de 2b ..... </span><br><span class="line">    //裸数据首字节为0x65,0x65&amp;ox1f=5,符合h264 nalu I帧定义</span><br></pre></td></tr></table></figure>
<p>B/P帧<br><img src="http://cyrus_huang.gitee.io/blog/2019/08/06/RTMP协议解析/b帧.png" alt=""></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">04 00 02 4b 00 01 66 09 01 00 00 00 27 01 00 00</span><br><span class="line">70 00 00 01 5d 41 9a 02 05 8e df a8 fd f5 1f b1</span><br><span class="line">9b bd 75 af ad 7d 6b eb 5f 5a c4 6f 11 8a fd 6b</span><br><span class="line">11 8a fd 6b eb 5f 5a fa d7 d5 b1 98 ae a8 6e ef</span><br><span class="line">89 f3 92 21 c8 a5 7f 5a c5 79 d5 fd 6b da d6 2b</span><br><span class="line">fa d6 2b 78 ad e2 b7 f5 ac ff d6 be b5 62 71 5c</span><br><span class="line">42 bc 5f af ad 67 7c 77 7c ea 97 ad 62 9d b8 9d</span><br><span class="line">==============     解析       ==============</span><br><span class="line">header:解析方式与其它视频帧一致</span><br><span class="line">	04 00 02 4b 00 01 66 09 01 00 00 00</span><br><span class="line">    </span><br><span class="line">body:</span><br><span class="line">	27: avc 非关键帧</span><br><span class="line">    01: 视频裸数据，27 01即B帧/P帧</span><br><span class="line">    00 00 70：CompositionTime</span><br><span class="line">    00 00 01 5d：nalu size 裸数据长度349</span><br><span class="line">    Raw Data: 41 9a 02 05 8e df a8 fd f5 1f b1</span><br><span class="line">9b bd 75 af ad 7d 6b eb 5f 5a c4 6f 11 8a fd 6b</span><br><span class="line">11 8a fd 6b eb 5f 5a fa d7 d5 b1 98 ae.........</span><br><span class="line">	////裸数据首字节为0x41,0x41&amp;ox1f=1,符合h264 nalu B/P帧定义</span><br></pre></td></tr></table></figure>
<h5 id="最后再看看audio数据"><a href="#最后再看看audio数据" class="headerlink" title="最后再看看audio数据"></a>最后再看看audio数据</h5><p>首先看一下AAC sequence 参数块<br><img src="http://cyrus_huang.gitee.io/blog/2019/08/06/RTMP协议解析/audio参数.png" alt=""></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line">header的type id为0x08，即为音频</span><br><span class="line"></span><br><span class="line">body:</span><br><span class="line">    1）第一个字节af，a就是10代表的意思是AAC，Format of SoundData. The following values are defined:</span><br><span class="line">		0 = Linear PCM, platform endian</span><br><span class="line">		1 = ADPCM</span><br><span class="line">		2 = MP3</span><br><span class="line">		3 = Linear PCM, little endian</span><br><span class="line">		4 = Nellymoser 16 kHz mono</span><br><span class="line">		5 = Nellymoser 8 kHz mono</span><br><span class="line">		6 = Nellymoser</span><br><span class="line">		7 = G.711 A-law logarithmic PCM</span><br><span class="line">		8 = G.711 mu-law logarithmic PCM</span><br><span class="line">		9 = reserved</span><br><span class="line">		10 = AAC</span><br><span class="line">		11 = Speex</span><br><span class="line">		14 = MP3 8 kHz</span><br><span class="line">		15 = Device-specific sound</span><br><span class="line">		Formats 7, 8, 14, and 15 are reserved.</span><br><span class="line">		AAC is supported in Flash Player 9,0,115,0 and higher.</span><br><span class="line">		Speex is supported in Flash Player 10 and higher.</span><br><span class="line">	2）第一个字节中的后四位f代表如下</span><br><span class="line">		前2个bit的含义采样频率，这里是二进制11，代表44kHZ</span><br><span class="line">			Sampling rate. The following values are defined:</span><br><span class="line">			0 = 5.5 kHz</span><br><span class="line">			1 = 11 kHz</span><br><span class="line">			2 = 22 kHz</span><br><span class="line">			3 = 44 kHz</span><br><span class="line">		第3个bit，代表 音频用16位的</span><br><span class="line">			Size of each audio sample. This parameter only pertains to uncompressed formats. Compressed formats always decode to 16 bits internally.</span><br><span class="line">			0 = 8-bit samples</span><br><span class="line">			1 = 16-bit samples</span><br><span class="line">		第4个bit代表声道</span><br><span class="line">			Mono or stereo sound</span><br><span class="line">			0 = Mono sound</span><br><span class="line">			1 = Stereo sound</span><br><span class="line">    </span><br><span class="line">    第二个字节00，0 = AAC sequence header 参数，1 = AAC raw 裸数据</span><br><span class="line">    </span><br><span class="line">    后面：12 10 56 e5 00 详见码流结构参见“ISO-14496-3 Audio”中描述</span><br><span class="line">    或https://my.oschina.net/u/2326611/blog/854488</span><br></pre></td></tr></table></figure>
<p><img src="http://cyrus_huang.gitee.io/blog/2019/08/06/RTMP协议解析/audio_raw.png" alt=""></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">header的type id为0x08，即为音频</span><br><span class="line"></span><br><span class="line">body:</span><br><span class="line">	首字节af，解析方式与AAC sequence 参数块相同</span><br><span class="line">    第二个字节01 ，0 = AAC sequence header 参数，1 = AAC raw 裸数据</span><br></pre></td></tr></table></figure>


                
            </div>

            <!-- Comments -->
            
                <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                    


                </div>
            
        </div>
    </div>
</article>

    <!-- Footer -->
    <hr>

<!-- Footer -->
<footer>
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                <ul class="list-inline text-center">
                    

                    

                    
                        <li>
                            <a href="https://github.com/klugjo/hexo-theme-clean-blog" target="_blank">
                                <span class="fa-stack fa-lg">
                                    <i class="fa fa-circle fa-stack-2x"></i>
                                    <i class="fa fa-github fa-stack-1x fa-inverse"></i>
                                </span>
                            </a>
                        </li>
                    

                    

                    

                    
                </ul>
                <p class="copyright text-muted">&copy; 2020 Cyrus<br></p>
                <p class="copyright text-muted">Original Theme <a target="_blank" href="http://startbootstrap.com/template-overviews/clean-blog/">Clean Blog</a> from <a href="http://startbootstrap.com/" target="_blank">Start Bootstrap</a></p>
                <p class="copyright text-muted">Adapted for <a target="_blank" href="https://hexo.io/">Hexo</a> by <a href="http://www.codeblocq.com/" target="_blank">Jonathan Klughertz</a></p>
                <p class="copyright text-muted"><a href="http://www.beian.miit.gov.cn">粤ICP备18110122号-1</a></p>
            </div>
        </div>
    </div>
</footer>


    <!-- After footer scripts -->
    
<!-- jQuery -->
<script src="//code.jquery.com/jquery-2.1.4.min.js"></script>

<!-- Bootstrap -->
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>

<!-- Gallery -->
<script src="//cdnjs.cloudflare.com/ajax/libs/featherlight/1.3.5/featherlight.min.js" type="text/javascript" charset="utf-8"></script>

<!-- Disqus Comments -->



</body>

</html>